<template>
  <div class="koi-flex m-x-6px m-y-5px" v-loading="loading">
    <el-row :gutter="10">
      <el-col :span="24">
        <el-card class="rounded-md" shadow="never">
          <template #header>
            <div class="flex flex-items-center gap-6px">
              <el-icon :size="18">
                <Monitor />
              </el-icon>
              <div>基本信息</div>
            </div>
          </template>
          <div class="el-table el-table--enable-row-hover el-table--medium">
            <table cellspacing="0" style="width: 100%">
              <tbody>
                <tr>
                  <td class="el-table__cell is-leaf"><div class="cell">Redis版本</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.redis_version }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">运行模式</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.redis_mode == "standalone" ? "单机" : "集群" }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">端口</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.tcp_port }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">客户端数</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.connected_clients }}</div>
                  </td>
                </tr>
                <tr>
                  <td class="el-table__cell is-leaf"><div class="cell">运行时间(天)</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.uptime_in_days }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">使用内存</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.used_memory_human }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">使用CPU</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ parseFloat(redis.info.used_cpu_user_children).toFixed(2) }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">内存配置</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.maxmemory_human }}</div>
                  </td>
                </tr>
                <tr>
                  <td class="el-table__cell is-leaf"><div class="cell">AOF是否开启</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.aof_enabled == "0" ? "否" : "是" }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">RDB是否成功</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">{{ redis.info.rdb_last_bgsave_status }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">Key数量</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.dbSize">{{ redis.dbSize }}</div>
                  </td>
                  <td class="el-table__cell is-leaf"><div class="cell">网络入口/出口</div></td>
                  <td class="el-table__cell is-leaf">
                    <div class="cell" v-if="redis.info">
                      {{ redis.info.instantaneous_input_kbps }}kps/{{ redis.info.instantaneous_output_kbps }}kps
                    </div>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </el-card>
      </el-col>

      <el-col :lg="12" :md="24" :sm="24" :xs="24" class="m-t-6px">
        <el-card class="rounded-md" shadow="never">
          <template #header>
            <div class="flex flex-items-center gap-6px">
              <el-icon :size="18">
                <PieChart />
              </el-icon>
              <div>命令统计</div>
            </div>
          </template>
          <div class="el-table el-table--enable-row-hover el-table--medium">
            <div ref="commandstatsRefChart" style="height: 420px" />
          </div>
        </el-card>
      </el-col>

      <el-col :lg="12" :md="24" :sm="24" :xs="24" class="m-t-6px">
        <el-card class="rounded-md" shadow="never">
          <template #header>
            <div class="flex flex-items-center gap-6px">
              <el-icon :size="18">
                <Odometer />
              </el-icon>
              <div>内存信息</div>
            </div>
          </template>
          <div class="el-table el-table--enable-row-hover el-table--medium">
            <div ref="usedmemoryRefChart" style="width: 100%; height: 420px" />
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts" name="redisPage">
import { ref, onMounted, onUnmounted } from "vue";
import { koiMsgError } from "@/utils/koi.ts";
import { getRedisInformation } from "@/api/monitor/redis/index.ts";
import * as echarts from "echarts";
import { useI18n } from "vue-i18n";

const { t } = useI18n();
// redis信息
const redis = ref<any>([]);
const loading = ref(false);

// 用于监听容器尺寸的ResizeObserver
const commandStatsResizeObserver = ref<ResizeObserver | null>(null);

/** 安全初始化图表 */
const safeInitCommandstatsChart = (retry = 0, maxRetries = 6) => {
  if (retry > maxRetries) {
    console.error("图表初始化失败：重试次数超限");
    return;
  }

  if (!commandstatsRefChart.value) {
    console.warn("图表容器未找到，延迟初始化");
    setTimeout(() => safeInitCommandstatsChart(retry + 1), 100);
    return;
  }

  // 检查容器尺寸是否有效
  const { clientWidth, clientHeight } = commandstatsRefChart.value;
  if (clientWidth <= 0 || clientHeight <= 0) {
    console.warn("图表容器尺寸无效，延迟初始化", { width: clientWidth, height: clientHeight });
    setTimeout(() => safeInitCommandstatsChart(retry + 1), 50);
    return;
  }

  // 如果已有图表实例，先销毁
  if (commandstatChartInstance.value) {
    commandstatChartInstance.value.dispose();
    commandstatChartInstance.value = null;
  }

  // 初始化图表
  commandstatChartInstance.value = echarts.init(commandstatsRefChart.value);
  initCommandstatsChart();
  // 设置ResizeObserver监听容器变化
  commandStatsResizeObserver.value = new ResizeObserver(() => {
    if (commandstatChartInstance.value) {
      commandstatChartInstance.value.resize();
    }
  });

  commandStatsResizeObserver.value.observe(commandstatsRefChart.value);

  // 图表自适应
  commandstatResizeChart();
  window.addEventListener("resize", commandstatResizeChart);
  // 获取接口数据
  handleGetServer();
  // tooltip刷新定时器
  handleTooltipTimer();
};

// 用于监听容器尺寸的ResizeObserver
const usedmemoryResizeObserver = ref<ResizeObserver | null>(null);

/** 安全初始化图表 */
const safeInitUsedmemoryChart = (retry = 0, maxRetries = 6) => {
  if (retry > maxRetries) {
    console.error("图表初始化失败：重试次数超限");
    return;
  }

  if (!usedmemoryRefChart.value) {
    console.warn("图表容器未找到，延迟初始化");
    setTimeout(() => safeInitUsedmemoryChart(retry + 1), 100);
    return;
  }

  // 检查容器尺寸是否有效
  const { clientWidth, clientHeight } = usedmemoryRefChart.value;
  if (clientWidth <= 0 || clientHeight <= 0) {
    console.warn("图表容器尺寸无效，延迟初始化", { width: clientWidth, height: clientHeight });
    setTimeout(() => safeInitUsedmemoryChart(retry + 1), 50);
    return;
  }

  // 如果已有图表实例，先销毁
  if (usedmemoryChartInstance.value) {
    usedmemoryChartInstance.value.dispose();
    usedmemoryChartInstance.value = null;
  }

  // 初始化图表
  usedmemoryChartInstance.value = echarts.init(usedmemoryRefChart.value);
  initUsedmemoryChart();
  // 设置ResizeObserver监听容器变化
  usedmemoryResizeObserver.value = new ResizeObserver(() => {
    if (usedmemoryChartInstance.value) {
      usedmemoryChartInstance.value.resize();
    }
  });

  usedmemoryResizeObserver.value.observe(usedmemoryRefChart.value);

  // 图表自适应
  usedmemoryResizeChart();
  window.addEventListener("resize", usedmemoryResizeChart);
};

onMounted(() => {
  safeInitCommandstatsChart();
  safeInitUsedmemoryChart();
});

onUnmounted(() => {
  window.removeEventListener("resize", commandstatResizeChart);
  window.removeEventListener("resize", usedmemoryResizeChart);
  // 销毁ResizeObserver
  if (commandStatsResizeObserver.value && commandstatsRefChart.value) {
    commandStatsResizeObserver.value.unobserve(commandstatsRefChart.value);
    commandStatsResizeObserver.value.disconnect();
  }

  // 销毁Echarts图表
  if (commandstatChartInstance.value) {
    commandstatChartInstance.value.dispose();
    commandstatChartInstance.value = null;
  }

  // 清除tooltip刷新定时器
  clearInterval(tooltipTimer.value);
  tooltipTimer.value = null;

  // 销毁Echarts图表
  if (usedmemoryChartInstance.value) {
    usedmemoryChartInstance.value.dispose();
    usedmemoryChartInstance.value = null;
  }
});

/** 获取服务监控数据 */
const handleGetServer = async () => {
  try {
    redis.value = [];
    loading.value = true;
    const res: any = await getRedisInformation();
    redis.value = res.data;
    commandstatUpdateChart();
    usedmemoryUpdateChart();
    loading.value = false;
  } catch (error) {
    console.log(error);
    koiMsgError(t("msg.fail"));
  }
};

// 统计命令信息
const commandstatsRefChart = ref();
// 使用内存
const usedmemoryRefChart = ref();
// 初始化图表对象
const commandstatChartInstance = ref();
const usedmemoryChartInstance = ref();

// tooltip定时器ID-用于清除定时器
const tooltipTimer = ref();

// 统计命令信息图表
const initCommandstatsChart = () => {
  if (!commandstatsRefChart.value || !commandstatChartInstance.value) return;

  const initOption = {
    tooltip: {
      trigger: "item",
      formatter: "{a} <br/>{b} : {c} ({d}%)"
    },
    series: [
      {
        name: "命令",
        type: "pie",
        roseType: "radius",
        // 环形图大小
        radius: ["45%", "70%"],
        // 环形图位置
        center: ["50%", "50%"],
        animationEasing: "cubicInOut",
        animationDuration: 1000
      }
    ],
    itemStyle: {
      borderRadius: 10,
      borderColor: "#fff",
      borderWidth: 2
    },
    emphasis: {
      label: {
        show: true,
        fontSize: "14",
        fontWeight: "bold"
      },
      itemStyle: {
        shadowBlur: 10,
        shadowOffsetX: 0,
        shadowColor: "rgba(0, 0, 0, 0.5)"
      }
    }
  };

  // 图表初始化配置
  commandstatChartInstance.value.setOption(initOption);

  if (commandstatChartInstance.value) {
    // 鼠标移入停止定时器
    commandstatChartInstance.value.on("mouseover", () => {
      if (tooltipTimer.value) {
        clearInterval(tooltipTimer.value);
        tooltipTimer.value = null;
      }
    });

    // 鼠标移入启动定时器
    commandstatChartInstance.value.on("mouseout", () => {
      // 只有当前没有定时器时才启动
      if (!tooltipTimer.value) {
        handleTooltipTimer();
      }
    });
  }
};

const commandstatUpdateChart = () => {
  // 处理图表需要的数据
  const dataOption = {
    series: [
      {
        data: redis.value.commandStats
      }
    ]
  };
  // 图表数据变化配置
  commandstatChartInstance.value?.setOption(dataOption);
  // 重新渲染图表
  commandstatChartInstance.value?.resize();
};

const commandstatResizeChart = () => {
  // 处理图表需要的数据
  const resizeOption = {
    series: [
      {
        radius: ["45%", "70%"],
        center: ["50%", "50%"]
      }
    ]
  };
  // 图表数据变化配置
  commandstatChartInstance.value?.setOption(resizeOption);
  // 重新渲染图表
  commandstatChartInstance.value?.resize();
};

// 内存信息图表
const initUsedmemoryChart = () => {
  // 定义实例
  if (!usedmemoryRefChart.value || !usedmemoryChartInstance.value) return;

  const initOption = {
    series: [
      {
        name: "峰值",
        type: "gauge",
        min: 0,
        max: 1000
      }
    ]
  };

  // 图表初始化配置
  usedmemoryChartInstance.value?.setOption(initOption);
};

const usedmemoryUpdateChart = () => {
  // 处理图表需要的数据
  const dataOption = {
    tooltip: {
      formatter: "{b} <br/>{a} : " + redis.value.info.used_memory_human
    },
    series: [
      {
        detail: {
          formatter: redis.value.info.used_memory_human
        },
        data: [
          {
            value: parseFloat(redis.value.info.used_memory_human),
            name: "内存消耗"
          }
        ]
      }
    ]
  };
  // 图表数据变化配置
  usedmemoryChartInstance.value?.setOption(dataOption);
  // 重新渲染图表
  usedmemoryChartInstance.value?.resize();
};

const usedmemoryResizeChart = () => {
  // 重新渲染图表
  usedmemoryChartInstance.value?.resize();
};

/** tooltip定时器 */
const handleTooltipTimer = () => {
  let index = 0; // 播放所在下标
  tooltipTimer.value = setInterval(() => {
    // echarts实现定时播放tooltip
    commandstatChartInstance.value.dispatchAction({
      type: "showTip",
      position: function (point: any) {
        return {
          left: point[0] + 10, // 水平方向偏移量
          top: point[1] - 10 // 垂直方向偏移量
        };
      },
      seriesIndex: 0,
      dataIndex: index
    });
    index++;
    if (index > redis.value.commandStats.length) {
      index = 0;
    }
  }, 2000);
};
</script>

<style scoped></style>
